package com.su.dolphin.utils.mgr;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;

import com.su.dolphin.utils.LogUtil;
import com.su.dolphin.utils.ui.TipsUtil;
import com.su.dolphin.view.fragment.BaseFragment;

/**
 * 一个demo 在百度网盘 -> 工作 TVMao中
 *
 * @author gaoshuai
 */
public class DpFragmentManager {

    private static DpFragmentManager mInstance;
    private List<String> mFragmentsNotHiden = new ArrayList<String>();
    //private Stack<Fragment> fragmentStack = new Stack<Fragment>();

    private DpFragmentManager() {
    }

    public static DpFragmentManager i() {
        if (mInstance == null) {
            mInstance = new DpFragmentManager();
        }
        return mInstance;
    }

    /**
     * 把clazz添加到不隐藏队列, 在switchFragment的时候不会被隐藏
     *
     * @param clazz
     */
    public void addNotHidedList(Class<?> clazz) {
        String clazzName = clazz.getName();
        if (!mFragmentsNotHiden.contains(clazzName)) {
            mFragmentsNotHiden.add(clazzName);
        }
    }

    /**
     * 把不隐藏队列移除, 在switchFragment的时候clazz会被隐藏
     *
     * @param clazz
     */
    public void removeFromHidenList(Class<?> clazz) {
        mFragmentsNotHiden.remove(clazz);
    }

    /**
     * switch = 把一个fragment添加到Activity并显示出来, 如果已经添加过, 会调用fragment的update函数
     *
     * @param fragmentActivity
     * @param layout
     * @param clazz
     * @param bundle
     * @param addToBackStack
     */
    public void switchFragment(FragmentActivity fragmentActivity, int layout,
                               Class<?> clazz, Bundle bundle, boolean addToBackStack) {
        String clazzName = clazz.getName();
        FragmentManager fm = fragmentActivity.getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();

        List<Fragment> fragments = fm.getFragments();
        if (fragments != null) {
            for (Fragment fragment : fragments) {
                if (fragment != null
                        && !mFragmentsNotHiden.contains(fragment.getClass()
                        .getName())) {
                    ft.hide(fragment);
                }
            }
        }

        Fragment fragment = fm.findFragmentByTag(clazzName);
        if (fragment == null) {
            fragment = Fragment
                    .instantiate(fragmentActivity, clazzName, bundle);
            ft.add(layout, fragment, clazzName);
            if (addToBackStack) {
                ft.addToBackStack(null);
            }
            LogUtil.i("add");
        } else {
            ((BaseFragment) fragment).update(bundle);
            LogUtil.i("show and update");
        }
        ft.show(fragment);
        // ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.commit();
    }

    public void switchFragment(FragmentActivity fragmentActivity, int layout,
                               Class<?> clazz, boolean addToBackStack) {
        switchFragment(fragmentActivity, layout, clazz, null, addToBackStack);
    }

    public void switchFragment(FragmentActivity fragmentActivity, int layout,
                               Class<?> clazz, Bundle bundle) {
        switchFragment(fragmentActivity, layout, clazz, bundle, false);
    }

    public void switchFragment(FragmentActivity fragmentActivity, int layout,
                               Class<?> clazz) {
        switchFragment(fragmentActivity, layout, clazz, null, false);
    }

    /**
     * 向布局中替换一个fragment, 会导致之前布局的fragment都被去掉 注意, 这个和switchFragment 混用可能有问题
     *
     * @param fragmentActivity
     * @param layout
     * @param clazz
     * @param bundle
     */
    public void replaceFragment(FragmentActivity fragmentActivity, int layout,
                                Class<?> clazz, Bundle bundle, boolean addToBackStack) {
        FragmentManager fm = fragmentActivity.getSupportFragmentManager();
        String clazzName = clazz.getName();
        FragmentTransaction ft = fm.beginTransaction();
        Fragment fragment = Fragment.instantiate(fragmentActivity, clazzName,
                bundle);
        ft.replace(layout, fragment, clazzName);
        if (addToBackStack) {
            ft.addToBackStack(null);
        }
        ft.commit();
    }

    public void replaceFragment(FragmentActivity fragmentActivity, int layout,
                                Class<?> clazz, boolean addToBackStack) {
        replaceFragment(fragmentActivity, layout, clazz, null, addToBackStack);
    }

    public void replaceFragment(FragmentActivity fragmentActivity, int layout,
                                Class<?> clazz) {
        replaceFragment(fragmentActivity, layout, clazz, null, false);
    }

    /**
     * 隐藏某个Fragment
     *
     * @param fragmentActivity
     * @param clazz
     */
    public void hideFragment(FragmentActivity fragmentActivity, Class<?> clazz) {
        FragmentManager fm = fragmentActivity.getSupportFragmentManager();
        Fragment fragment = fm.findFragmentByTag(clazz.getName());
        if (fragment != null) {
            FragmentTransaction ft = fm.beginTransaction();
            ft.hide(fragment);
            ft.commit();
        }
    }

    /**
     * 隐藏所有的Fragment
     *
     * @param fragmentActivity
     */
    public void hideAllFragment(FragmentActivity fragmentActivity) {
        FragmentManager fm = fragmentActivity.getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        List<Fragment> fragments = fm.getFragments();
        if (fragments != null) {
            for (Fragment fragment : fragments) {
                ft.hide(fragment);
            }
            ft.commit();
        }
    }

    /**
     * 更新类名是clazz的fragment
     *
     * @param fragmentActivity
     * @param clazz
     * @param bundle
     */
    public static void update(FragmentActivity fragmentActivity,
                              Class<?> clazz, Bundle bundle) {
        String clazzName = clazz.getName();
        FragmentManager fm = fragmentActivity.getSupportFragmentManager();
        Fragment fragment = fm.findFragmentByTag(clazzName);
        if (fragment != null) {
            ((BaseFragment) fragment).update(bundle);
            TipsUtil.toast("updated");
        }
    }

    public static Fragment findFragmentByTag(FragmentActivity fragmentActivity,
                                             Class<?> clazz) {
        String clazzName = clazz.getName();
        FragmentManager fm = fragmentActivity.getSupportFragmentManager();
        Fragment fragment = fm.findFragmentByTag(clazzName);
        return fragment;

    }

    /**
     * 添加一个没有视图的fragment
     *
     * @param fragmentActivity
     * @param clazz
     * @param bundle
     */
    public void addFragment(FragmentActivity fragmentActivity, Class<?> clazz,
                            Bundle bundle) {
        FragmentManager fm = fragmentActivity.getSupportFragmentManager();
        String clazzName = clazz.getName();
        FragmentTransaction ft = fm.beginTransaction();
        Fragment fragment = Fragment.instantiate(fragmentActivity, clazzName,
                bundle);
        ft.add(0, fragment, clazz.getName());
        ft.commit();

    }

    /**
     * 监听返回栈的变化
     *
     * @param fragmentActivity
     * @param onBackStackChangedListener
     */
    public void addOnBackStackChangedListener(
            FragmentActivity fragmentActivity,
            FragmentManager.OnBackStackChangedListener onBackStackChangedListener) {
        final FragmentManager fm = fragmentActivity.getSupportFragmentManager();
        fm.addOnBackStackChangedListener(onBackStackChangedListener);
    }

    /**
     * 获取当前Fragment堆的数目
     *
     * @param fragmentActivity
     * @return
     */
    public int getBackStackEntryCount(FragmentActivity fragmentActivity) {
        FragmentManager fm = fragmentActivity.getSupportFragmentManager();
        return fm.getBackStackEntryCount();
    }

    /**
     * 如果当前返回栈不为0 , 弹出上面的fragment
     *
     * @return true 成功弹出fragment. false 已经是最底层的fragment了
     */
    public boolean goBack(FragmentActivity fragmentActivity) {
        FragmentManager fm = fragmentActivity.getSupportFragmentManager();
        if (fm.getBackStackEntryCount() <= 0) {
            return false;
        }
        fm.popBackStack();
        return true;
    }
}
